package uncharteddal

import (
	"fmt"

	"github.com/garyburd/redigo/redis"

	"public.com/goutil/logUtil"

	"7qule.com/sd3/CrossServer/src/common/onlinelog"
	"7qule.com/sd3/CrossServer/src/dal"
	"7qule.com/sd3/CrossServer/src/model/redisKey"
	"7qule.com/sd3/CrossServer/src/model/uncharted"
)

func UpdateTerritoryInfo(mapId int8, pointId int, playerId string, heroInfo string, fightData string, territoryTime int64) (err error) {
	conn := dal.GetRedisPool().GetConnection()
	defer conn.Close()
	_, err = conn.Do("HMSET", redisKey.GetTerritoryKey(mapId, pointId),
		redisKey.Uncharted_PlayerId, playerId,
		redisKey.Uncharted_FightData, fightData,
		redisKey.Uncharted_TerritoryTime, territoryTime,
		redisKey.Uncharted_HeroInfo, heroInfo)
	if err != nil {
		logUtil.Log(fmt.Sprintf("Redis 更新uncharted据点信息出错1，错误信息为：%s", err), logUtil.Error, true)
		return
	}

	return nil
}

func GetAllTerritoryInfo() (fightData map[int8]map[int]*uncharted.MatchPlayer, territoryTimeData map[int8]map[int]int64, exists bool, err error) {
	var keys []string
	keys, exists, err = getAllTerritoryKeys()
	if exists == false || err != nil {
		return
	}

	fightData = make(map[int8]map[int]*uncharted.MatchPlayer, 4)
	territoryTimeData = make(map[int8]map[int]int64, 4)

	conn := dal.GetRedisPool().GetConnection()
	defer conn.Close()

	// 遍历所有的Key
	for _, key := range keys {
		mapId, pointId, ok := redisKey.ParseTerritoryKey(key)
		if ok == false {
			onlinelog.ErrorLog("ParseTerritoryKey转换出错，key:%v", key)
			continue
		}

		var fihtDataItem string
		var territoryTime int64
		var playerId string
		var heroInfo string

		reply, err := conn.Do("HMGET",
			key,
			redisKey.Uncharted_PlayerId,
			redisKey.Uncharted_FightData,
			redisKey.Uncharted_TerritoryTime,
			redisKey.Uncharted_HeroInfo,
		)

		if err != nil {
			logUtil.Log(fmt.Sprintf("从Redis中获取uncharted据点信息出错1，错误信息为：%v", err), logUtil.Error, true)
			continue
		}

		values, err := redis.Values(reply, err)
		if err != nil {
			logUtil.Log(fmt.Sprintf("从Redis中获取uncharted据点信息出错2，错误信息为：%v", err), logUtil.Error, true)
			continue
		}

		// 创建对象并添加到列表中
		if _, err := redis.Scan(values, &playerId, &fihtDataItem, &territoryTime, &heroInfo); err != nil {
			logUtil.Log(fmt.Sprintf("从Redis中获取uncharted据点信息出错3，错误信息为：%v", err), logUtil.Error, true)
		}

		var playerData *uncharted.MatchPlayer
		if len(playerId) > 0 {
			err, exists, playerData = getPlayerAllInfo(playerId, conn)
			if err != nil || exists == false {
				continue
			}
		}

		playerData.FightInfo = fihtDataItem
		playerData.HeroInfo = heroInfo

		// 玩家信息
		fightDataByMapId, exist := fightData[mapId]
		if exist == false {
			fightDataByMapId = make(map[int]*uncharted.MatchPlayer, 4)
			fightData[mapId] = fightDataByMapId
		}
		fightDataByMapId[pointId] = playerData

		// 占领时间
		territoryTimeItemByMapId, exist := territoryTimeData[mapId]
		if exist == false {
			territoryTimeItemByMapId = make(map[int]int64, 4)
			territoryTimeData[mapId] = territoryTimeItemByMapId
		}
		territoryTimeItemByMapId[pointId] = territoryTime
	}

	return fightData, territoryTimeData, true, nil
}

func getAllTerritoryKeys() ([]string, bool, error) {
	conn := dal.GetRedisPool().GetConnection()
	defer conn.Close()

	reply, err := conn.Do("KEYS", fmt.Sprintf("%s*", redisKey.TerritoryPrefix))
	if err != nil {
		if err == redis.ErrNil {
			return nil, false, nil
		} else {
			logUtil.Log(fmt.Sprintf("从Redis中获取uncharted据点Keys出错1，错误信息为：%s", err), logUtil.Error, true)
			return nil, false, err
		}
	}

	keys, err := redis.Strings(reply, err)
	if err != nil {
		if err == redis.ErrNil {
			return nil, false, nil
		} else {
			logUtil.Log(fmt.Sprintf("从Redis中获取uncharted据点Keys出错2，错误信息为：%s", err), logUtil.Error, true)
			return nil, false, err
		}
	}

	return keys, true, nil
}

// 删除所有占领数据
// 返回值:
// err:错误信息
func DeleteAllTerritoryData() (err error) {
	var keys []string
	keys, _, err = getAllTerritoryKeys()
	if err != nil || len(keys) <= 0 {
		return
	}

	conn := dal.GetRedisPool().GetConnection()
	defer conn.Close()

	for _, key := range keys {
		if _, err := conn.Do("DEL", key); err != nil {
			logUtil.Log(fmt.Sprintf("赛季结束后删除据点占领数据出错，错误信息为：%s", err), logUtil.Error, true)
			continue
		}
	}

	return nil
}

// 删除所有占领数据
// 返回值:
// err:错误信息
func DeleteTerritoryData(mapId int8, pointId int) (err error) {
	key := redisKey.GetTerritoryKey(mapId, pointId)

	conn := dal.GetRedisPool().GetConnection()
	defer conn.Close()

	if _, err := conn.Do("DEL", key); err != nil {
		logUtil.Log(fmt.Sprintf("赛季结束后删除据点占领数据出错，错误信息为：%s", err), logUtil.Error, true)
		return err
	}

	return nil
}
